<template>
  <div class="mod-depart">
    <el-container>
      <el-aside style="width: 35%; min-width: 400px">
        <el-card class="box-card">
          <template #header>
            <div class="clearfix">
              <span class="d-title">部门信息</span>
            </div>
          </template>
          <div class="toolbar-box">
            <el-row :gutter="20" class="toolbar-box">
              <el-col :span="11">
                <el-input placeholder="输入关键字进行过滤" v-model="filterTreeText" />
              </el-col>
              <el-col :span="13">
                <el-button-group class="toolbar-btngroup fr">
                  <el-button v-if="admin.isAuth('admin:depart:save')" @click="() => addDepartEvent('add-root')" type="primary"> 新增 </el-button>
                  <el-button v-if="admin.isAuth('admin:depart:save')" @click="() => updateDepartEvent()" type="warning"> 修改 </el-button>
                  <el-button v-if="admin.isAuth('admin:depart:delete')" @click="() => deleteDepartEvent()" type="danger"> 删除 </el-button>
                </el-button-group>
              </el-col>
            </el-row>
          </div>
          <div style="height: 410px">
            <el-scrollbar style="height: 100%">
              <el-tree
                node-key="id"
                class="filter-tree"
                :props="tree.props"
                :data="tree.data"
                highlight-current
                empty-text="木有数据~"
                v-loading.lock="tree.loading"
                element-loading-text="拼命加载中"
                :expand-on-click-node="false"
                :default-expanded-keys="tree.expandedKeys"
                @node-expand="treeNodeExpandEvent"
                @node-collapse="treeNodeCollapseEvent"
                default-expand-all
                :filter-node-method="filterTreeNode"
                ref="treeRef"
              >
                <template #default="{ node, data }">
                  <span class="custom-tree-node">
                    <span>{{ node.label }} - [{{ data.attributes && data.attributes.code }}]&nbsp;&nbsp;</span>
                    <span class="fr">
                      <el-button v-if="admin.isAuth('admin:depart:save')" size="small" type="primary" link @click="() => addDepartEvent('add-node', data)">
                        新增 
                      </el-button>
                      <el-button v-if="admin.isAuth('admin:depart:user-list')" size="small" type="info" link @click="() => loadUserTableEvent(node, data)">
                        用户
                      </el-button>
                    </span>
                  </span>
                </template>
              </el-tree>
            </el-scrollbar>
          </div>
        </el-card>
      </el-aside>
      <el-main v-if="table.show" style="padding: 0 20px">
        <el-card class="box-card">
          <template #header>
            <div class="clearfix">
              <span class="d-title">部门[{{ (tree.selectData && tree.selectData.name) || "" }}] - 用户管理</span>
            </div>
          </template>
          <data-table ref="dataTableRef" name="depart-user" :init="true" :url="table.url">
            <!-- ------------------------------------------ 工具栏 ------------------------------------------ -->
            <template v-slot:toolbar>
              <el-button-group>
                <el-button v-if="admin.isAuth('admin:depart:unallocated-user-list')" @click="() => saveOrUpdateRelationEvent()" type="primary">
                  新增
                </el-button>
                <el-button v-if="admin.isAuth('admin:user:delete')" @click="() => deleteUserRelationEvent()" type="danger">
                  删除
                </el-button>
              </el-button-group>
            </template>
            <!-- ---------------------------------------- 数据表格列 ---------------------------------------- -->
            <el-table-column fixed prop="username" align="center" label="用户名" width="120" />
            <el-table-column prop="fullname" align="center" label="用户姓名" width="140" />
            <el-table-column prop="status" align="center" label="状态">
              <template #default="scope">
                <el-tag v-if="scope.row.status === '0'" size="small" type="danger">禁用</el-tag>
                <el-tag v-else size="small">正常</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="mail" show-overflow-tooltip align="left" label="邮箱" width="180" />
            <el-table-column prop="phone" show-overflow-tooltip align="center" label="手机号" width="160" />
          </data-table>
        </el-card>
      </el-main>
    </el-container>
    <!-- 弹窗, 新增 / 修改 -->
    <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdateRef" @initDepartTreeData="initDepartTreeData" />
    <depart-user-relation v-if="addOrUpdateRelationVisible" ref="departUserRelationRef" @initUserTableData="initUserTableData" />
  </div>
</template>

<script lang="ts" setup>
import admin from "@/utils/admin";
import http from "@/utils/httpRequest";
import { ref, nextTick, reactive, watch, onMounted } from "vue";
import { ElTree, ElMessage, ElMessageBox } from "element-plus";

import AddOrUpdate from "./depart-add-or-update.vue";
import DepartUserRelation from "./depart-user-relation.vue";

// 部门树形结构
const tree = reactive({
  // 是否正在加载
  loading: true,
  // 部门树数据
  data: [],
  // 当前树选中的节点
  selectData: undefined,
  // 部门树默认属性
  props: {
    label: "name",
    children: "children",
  },
  // 展开列表
  expandedKeys: [],
});

// 部门人员关系列表
const table = reactive({
  // 是否显示用户管理列表
  show: false,
  // 请求地址
  url: "",
});

// 菜单树过滤文本
const filterTreeText = ref("");

// 新增修改弹窗是否显示
const addOrUpdateVisible = ref(false);

// 部门用户弹窗是否显示
const addOrUpdateRelationVisible = ref(false);

// 数据表格引用
const dataTableRef = ref();

// 弹窗引用
const addOrUpdateRef = ref();

// 部门用户关系弹窗
const departUserRelationRef = ref();

// 部门树引用
const treeRef = ref<InstanceType<typeof ElTree>>();

// 监听查询内容变化
watch(filterTreeText, (n, o) => {
  treeRef.value!.filter(n);
});

// 组件挂载完成后执行
onMounted(() => {
  // 左侧加载菜单
  initDepartTreeData();
});

// 左侧加载菜单
const initDepartTreeData = () => {
  tree.loading = true;
  http
    .get({
      url: '/depart/tree',
    })
    .then(({ data }) => {
      if (http.success(data)) {
        tree.data = data.body;
      }
      tree.loading = false;
    });
};

// 新增或者修改部门
const addDepartEvent = async (action, data = null) => {
  addOrUpdateVisible.value = true;
  await nextTick();
  addOrUpdateRef.value.initForm(action, action === "add-root" ? tree.data : data);
};

// 修改部门
const updateDepartEvent = async () => {
  let node = treeRef.value.getCurrentNode();
  if (!node) {
    ElMessage.error("请先选择要修改的部门！");
    return;
  }
  addOrUpdateVisible.value = true;
  await nextTick();
  addOrUpdateRef.value.initForm("update-node", node);
};

// 新增部门用户关联关系事件
const saveOrUpdateRelationEvent = async () => {
  addOrUpdateRelationVisible.value = true;
  await nextTick();
  departUserRelationRef.value.initForm(tree.selectData);
};

// 查看菜单下请求列表
const loadUserTableEvent = async (node, data) => {
  tree.selectData = data;
  table.url = `/depart/user-list?departId=${data.id}`;
  table.show = true;
  await nextTick();
  initUserTableData();
};

// 加载部门用户列表
const initUserTableData = () => {
  dataTableRef.value.loadTableData();
};

// 删除部门
const deleteDepartEvent = () => {
  let node = treeRef.value.getCurrentNode();
  if (!node) {
    ElMessage.error("请先选择要删除的菜单！");
    return;
  }
  ElMessageBox
    .confirm(`确定要删除部门[${node.name}]吗?`, "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    })
    .then(() => {
      http
        .post({
          url: `/depart/delete?departId=${node.id}`,
        })
        .then(({ data }) => {
          if (http.success(data, true, true)) {
            initDepartTreeData();
          }
        });
    })
    .catch(()=>{});
};

// 删除
const deleteUserRelationEvent = () => {
  let datas = dataTableRef.value.getSelection();
  if (!datas || datas.length <= 0) {
    ElMessage.error("请先选择要删除的数据！");
    return;
  }
  ElMessageBox
    .confirm(`确定要把选中的[${datas.length}]个用户从部门[${tree.selectData.name}]移除吗?`, "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    })
    .then(() => {
      let userIds = [];
      for (let i = 0; i < datas.length; i++) {
        userIds.push(datas[i].id);
      }
      http
        .post({
          url: "/depart/delete-relation",
          data: {
            departId: tree.selectData.id,
            userIds: userIds,
          },
        })
        .then(({ data }) => {
          if (http.success(data, true, true)) {
            initUserTableData();
          }
        });
    })
    .catch(()=>{});
};

// 菜单展开事件
const treeNodeExpandEvent = (data) => {
  if (tree.expandedKeys.indexOf(data.id) === -1) {
    tree.expandedKeys.push(data.id);
  }
};

// 菜单关闭事件
const treeNodeCollapseEvent = (data) => {
  let expandedKeys = tree.expandedKeys;
  for (let i = 0; i < expandedKeys.length; i++) {
    if (expandedKeys[i] === data.id) {
      expandedKeys.splice(i, 1);
    }
    let children = data.children;
    if (children && children.length > 0) {
      for (let h = 0; h < children.length; h++) {
        treeNodeCollapseEvent(children[h]);
      }
    }
  }
};

// 过滤菜单
const filterTreeNode = (value, data) => {
  if (!value) {
    return true;
  }
  return data.name.indexOf(value) !== -1;
};
</script>

<style lang="scss">
.mod-depart {

  .d-title {
    font-size: 16px;
    font-weight: 600;
  }

  .toolbar-box {
    margin: 10px 0;
  }

  .el-tree-node__label {
    width: 100%;
  }
}
</style>